package org.openbpm.bpm.engine.plugin.runtime.abstact;

import cn.hutool.core.collection.CollectionUtil;
import org.openbpm.bpm.api.constant.ExtractType;
import org.openbpm.bpm.api.engine.plugin.def.BpmUserCalcPluginDef;
import org.openbpm.bpm.engine.model.BpmIdentity;
import org.openbpm.bpm.engine.plugin.plugindef.AbstractUserCalcPluginDef;
import org.openbpm.bpm.engine.plugin.runtime.BpmUserCalcPlugin;
import org.openbpm.bpm.engine.plugin.session.BpmUserCalcPluginSession;
import org.openbpm.org.api.model.IUser;
import org.openbpm.org.api.service.UserService;
import org.openbpm.sys.api.model.SysIdentity;

import javax.annotation.Resource;
import java.util.*;

@lombok.extern.slf4j.Slf4j
public abstract class AbstractUserCalcPlugin<M extends BpmUserCalcPluginDef> extends Object implements BpmUserCalcPlugin<M> {
    @Resource
    protected UserService userService;

    @Override
    public List<SysIdentity> execute(BpmUserCalcPluginSession pluginSession, M pluginDef) {
        if (pluginSession.isPreViewModel().booleanValue() &&
                !supportPreView()) {
            return Collections.emptyList();
        }
        List<SysIdentity> list = queryByPluginDef(pluginSession, pluginDef);
        if (CollectionUtil.isEmpty(list)) {
            return list;
        }
        ExtractType extractType = ((AbstractUserCalcPluginDef)pluginDef).getExtract();
        Set<SysIdentity> set = new LinkedHashSet<SysIdentity>();
        List<SysIdentity> rtnList = new ArrayList<SysIdentity>();
        list = extract(list, extractType);
        set.addAll(list);
        rtnList.addAll(set);
        return rtnList;
    }

    protected List<SysIdentity> extract(List<SysIdentity> bpmIdentities, ExtractType extractType) {
        if (CollectionUtil.isEmpty(bpmIdentities)) {
            return Collections.EMPTY_LIST;
        }
        if (extractType == ExtractType.EXACT_NOEXACT) {
            return bpmIdentities;
        }
        return extractBpmIdentity(bpmIdentities);
    }

    protected List<SysIdentity> extractBpmIdentity(List<SysIdentity> bpmIdentities) {
        List<SysIdentity> results = new ArrayList<SysIdentity>();
        for (SysIdentity bpmIdentity : bpmIdentities) {
            if ("user".equals(bpmIdentity.getType())) {
                results.add(bpmIdentity);
                continue;
            }
            List<IUser> users = (List<IUser>)this.userService.getUserListByGroup(bpmIdentity.getType(), bpmIdentity.getId());
            for (IUser user : users) {
                results.add(new BpmIdentity(user));
            }
        }
        return results;
    }

    public boolean supportPreView() { return true; }

    protected abstract List<SysIdentity> queryByPluginDef(BpmUserCalcPluginSession paramBpmUserCalcPluginSession, M paramM);
}
